package org.example.analysis.service.dataobj;

import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.example.analysis.model.MethodComplexity;
import org.example.analysis.model.entity.JavaMethodInfo;

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

/**
 * 方法信息数据对象
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class MethodDataObject extends BaseDataObject {
    /**
     * 所属类ID
     */
    private Long classId;
    private String className;
    
    /**
     * 方法名
     */
    private String methodName;
    
    /**
     * 返回类型
     */
    private String returnType;
    
    /**
     * 方法注释
     */
    private String comment;
    
    /**
     * 访问修饰符
     */
    private String accessModifier;
    
    /**
     * 代码行数
     */
    private Integer codeLines;
    
    /**
     * 参数列表
     */
    private List<ParameterDataObject> parameters = new ArrayList<>();
    
    /**
     * 方法注解列表
     */
    private List<String> annotations = new ArrayList<>();
    
    /**
     * 方法修饰符列表
     */
    private List<String> modifiers = new ArrayList<>();
    
    /**
     * 是否是入口方法
     */
    private boolean isEntryPoint;
    
    /**
     * 入口类型（如：CONTROLLER, SERVICE等）
     */
    private String entryType;
    
    /**
     * 请求URL（针对Controller方法）
     */
    private String requestUrl;
    
    /**
     * 请求方法（GET, POST等）
     */
    private String requestMethod;
    
    /**
     * 方法体
     */
    private String methodBody;
    
    /**
     * 抛出的异常列表
     */
    private List<String> throwsExceptions = new ArrayList<>();
    
    /**
     * 是否是抽象方法
     */
    private boolean isAbstract;
    
    /**
     * 是否是静态方法
     */
    private boolean isStatic;
    
    /**
     * 是否是构造方法
     */
    private boolean isConstructor;
    
    /**
     * 是否是重写方法
     */
    private boolean isOverride;
    
    /**
     * 调用的方法列表
     */
    private List<MethodDataObject> calledMethods = new ArrayList<>();
    
    /**
     * 使用的字段列表
     */
    private List<FieldDataObject> usedFields = new ArrayList<>();
    //private List<AnnotationExpr> annotationsExpr= Lists.newArrayList();
   // private MethodDeclaration methodDeclaration;
    private String methodComment;
    /**
     * 方法复杂度信息
     */
    private MethodComplexity methodComplexity;
    /**
     * 包含子方法的复杂度
     */
    private MethodComplexity subMethodComplexity;
    private Integer complexityScore;
    /**
     * 包含子方法的复杂度评分
     */
    private Integer subComplexityScore;

    /**
     * 生成方法参数的唯一标识
     * 格式: methodName(paramType1,paramType2)#returnType
     * 例如: 
     * - getUserById(Long)#User
     * - getUserByName(String)#User
     * - updateUser(Long,User)#void
     * 
     * @return 方法参数唯一标识
     */
    private String generateMethodParametersKey() {
        StringBuilder key = new StringBuilder();
        
        // 1. 添加方法名
        key.append(this.methodName);
        
        // 2. 添加参数类型列表
        key.append("(");
        if (this.parameters != null && !this.parameters.isEmpty()) {
            List<String> paramTypes = this.parameters.stream()
                .map(param -> {
                    String type = param.getParameterType();
                    // 处理泛型类型，只保留主类型
                    if (type.contains("<")) {
                        type = type.substring(0, type.indexOf("<"));
                    }
                    // 处理数组类型
                    type = type.replace("[]", "Array");
                    // 移除包名，只保留类名
                    if (type.contains(".")) {
                        type = type.substring(type.lastIndexOf(".") + 1);
                    }
                    return type;
                })
                .collect(Collectors.toList());
            key.append(String.join(",", paramTypes));
        }
        key.append(")");
        
        // 3. 添加返回类型
        if (this.returnType != null) {
            String returnTypeStr = this.returnType;
            // 处理泛型返回类型
            if (returnTypeStr.contains("<")) {
                returnTypeStr = returnTypeStr.substring(0, returnTypeStr.indexOf("<"));
            }
            // 处理数组返回类型
            returnTypeStr = returnTypeStr.replace("[]", "Array");
            // 移除包名，只保留类名
            if (returnTypeStr.contains(".")) {
                returnTypeStr = returnTypeStr.substring(returnTypeStr.lastIndexOf(".") + 1);
            }
            key.append("#").append(returnTypeStr);
        }
        
        return key.toString();
    }

    public String getParametersKey() {
        return generateMethodParametersKey();
    }

    public void addAnnotation(AnnotationExpr annotation) {
        //annotationsExpr.add(annotation);
        annotations.add("@" + annotation.getNameAsString());
    }

    /**
     * 转换为JavaMethodInfo对象
     */
    public JavaMethodInfo toJavaMethodInfo() {
        JavaMethodInfo methodInfo = new JavaMethodInfo();
        
        // 基本信息
        methodInfo.setClassId(classId)
                .setClassName(className)
                .setMethodName(methodName)
                .setMethodComment(comment)
                .setReturnType(returnType)
                .setAccessModifier(accessModifier);

        // 类型标记
        methodInfo.setConstructor(isConstructor);

        // 统计信息
        methodInfo.setCodeLines(codeLines);

        // 列表信息
        methodInfo.setModifiers(modifiers != null ? new ArrayList<>(modifiers) : new ArrayList<>())
                .setAnnotations(annotations != null ? new ArrayList<>(annotations) : new ArrayList<>());


        // 时间和更新信息
        methodInfo.setLastModifiedTime(getLastModifiedTime())
                .setCreatedAt(getCreatedAt())
                .setRefreshable(getRefreshable());

        return methodInfo;
    }
}